﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
using Milkify.Input;
using System.Text.RegularExpressions;
using System.Windows;

namespace Milkify.Data
{
    public class ErrorViewData
    {
        public string Title { get; private set; }
        public string Message { get; private set; }
        public ICommand NavigateToErrorHelpCommand { get; private set; }
        public ICommand SendBugReportCommand { get; private set; }
        public ICommand CopyErrorToClipboardCommand { get; private set; }
        public Exception Exception { get; private set; }
        public IEnumerable<Exception> InnerExceptions { get; private set; }

        public ErrorViewData(Exception e)
            : this(GetErrorTitle(e), e)
        {
        }

        public ErrorViewData(string title, Exception e)
            : this(title, e.Message, e)
        {
        }

        public ErrorViewData(string title, string message, Exception e)
        {
            Title = title;
            Message = message;
            Exception = e;
            NavigateToErrorHelpCommand = new DecoupledCommand<Exception>(NavigateToErrorHelp, CanNavigateToErrorHelp);
            SendBugReportCommand = new DecoupledCommand(SendBugReport);
            CopyErrorToClipboardCommand = new DecoupledCommand(CopyErrorToClipboard);

            if (Exception != null)
            {
                var innerExceptions = new List<Exception>();
                var innerException = Exception;
                while (innerException != null)
                {
                    innerExceptions.Add(innerException);
                    innerException = innerException.InnerException;
                }
                InnerExceptions = innerExceptions;
            }
        }

        private void NavigateToErrorHelp(Exception e)
        {
            System.Diagnostics.Process.Start(e.HelpLink);
        }

        private bool CanNavigateToErrorHelp(Exception e)
        {
            return (e != null && !string.IsNullOrEmpty(e.HelpLink));
        }

        private void SendBugReport()
        {
            System.Diagnostics.Process.Start("http://feedback.milkify.com");
        }

        private void CopyErrorToClipboard()
        {
            StringBuilder builder = new StringBuilder();
            builder.AppendLine("Milkify Bug Report");
            builder.AppendLine("==================");
            builder.AppendLine(Exception.ToString());

            Clipboard.SetData(DataFormats.Text, builder.ToString());
        }

        private static readonly Regex sExceptionTitleRegex = new Regex("[A-Z]+[a-z]+");

        private static string GetErrorTitle(Exception e)
        {
            string name = e.GetType().Name;
            if (name.EndsWith("Exception"))
                name = name.Substring(0, name.Length - "Exception".Length);

            StringBuilder title = new StringBuilder(name.Length + 5);
            foreach (Match match in sExceptionTitleRegex.Matches(name))
            {
                title.Append(match.Value);
                title.Append(" ");
            }
            title.Append("Error");
            return title.ToString();
        }
    }
}
